import { Cookies } from '@jcstdio/jc-utils/cache'
import axios from 'axios'

import { ref, type Ref } from 'vue'
import { GUEST_USER_NAME } from './sets'
import { _USER_TOKEN_KEY_ } from './enums'

const cookies = new Cookies()

// 已登陆的单个用户数据
interface UserStorage {
  usertoken: string
  username: string
  isStaff: boolean
  isDefault: boolean // 默认用户
}

declare type UsersStorage = UserStorage[]

/**
 * 作为唯一用户时，这是一个使用单例模式进行使用的用户类，不允许实例化多次。
 */
class BaseUser {
  private _password = ref<string | null>(null)
  private _username = ref<string | null>(null)
  private _userid = ref<string | null>(null)
  private _email = ref<string | null>(null)
  private _isStaff = ref<boolean | null>(null)
  private _last_login = ref<Date | null>(null)
  private _is_active = ref<boolean | null>(null)
  /**用于权限表 */
  private _permissions: string[] = []
  /**表示当前用户是否登陆 */
  private _loginState: 'unlogin' | 'logined' = 'unlogin'

  constructor() {}

  private _getLocalUserDatas(): UsersStorage {
    return JSON.parse(localStorage.get(_USER_TOKEN_KEY_))
  }

  /**从 localstorage 中加载用户数据*/
  public loadStorage() {
    const s = this._getLocalUserDatas()
  }

  /**
   * 将当前用户的信息存储到 localstorage
   * - 访客身份下调用该放法不会进行持久化
   */
  public saveStorage() {
    // if(){
    // }
  }

  /**密码格式校验器 */
  private _checkPasswordFormat(password: string) {
    const regex = /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)[a-zA-Z\d]{8,}$/
    return regex.test(password)
  }

  /**
   * 设置用户实例密码
   * - 仅仅是实例上的修改，不会发起数据提交；
   * - 如果要修改密码，应使用 modifyPassword 方法
   */
  public set password(password: string) {
    this._password.value = password
  }
  /**
   * 设置用户名
   * - 仅仅是实例上的修改，不会发起数据提交；
   */
  public set username(username: string) {
    this._username.value = username
  }

  public get username(): string {
    const _ = this._username.value
    if (_) {
      return _
    }
    return GUEST_USER_NAME
  }

  /**
   * ## 修改密码
   * - 修改密码必须在已经登陆某个账号的前提下进行，且需要用户的 `userid` 和 `token`；
   * - 一旦用户通过填写修改个人信息的表单，通过双向绑定的响应式数据时时对密码输入进行检查：
   *   - UI 检查密码合法性，如果不合法提示错误信息
   *   - 合法的前提下，UI 检查第二次密码是否与第一一致，如果不一致提示错误信息
   * - 用户确认发起提交时：
   *   - UI 发起人机校验：
   *     - 如果校验成功，则调用 `modifyPassword`
   * @param password 新密码
   */
  public modifyPassword(password: string) {
    // Use axios to call password setting API
    axios
      .post('/api/auth/setPassword', { token: cookies.get('token'), password: password })
      .then((response) => {
        this._password.value = password
        console.log(response)
      })
      .catch((error) => {
        console.error(error)
      })
  }

  /**
   * ## 用户注册
   * ### 1. 用户注册时需要提交以下信息：
   *  - 用户的常用邮箱（用于接收验证码）；
   *  - 用户密码（用于日后进行登陆），其中：
   *     - 通过 UI 校验二次密码输入的一致性；
   * ### 2. 当用户填写完表发起提交时：
   *  - 将表单中的用户名添加到用户实例的 _username 属性上
   *  - 将表单中的密码添加到用户实例的 _password 属性上
   * ### 3. 如果用户注册成功：
   *  - 返回的 response 应该为一个 JSON 字符串。
   *  - response JSON 应包含字段：
   *    - `userid`： 该用户注册成功后的身份唯一标识符
   *    - `token`: 该用户的唯一标识符
   *  - 注册成功后的用户在后端是未激活的状态，即 `is_actived = false`:
   *     - 触发 'user-register-succeeded' 事件以引导 UI 进入激活页面，该页面用于填写后端发送到用户邮箱的一次性激活码；
   *     -
   * ### 4. 如果用户注册失败：
   *   - 触发 'user-register-failed' 事件，这个事件主要用户通知 UI 做相应的处理。
   */
  public register() {
    // 先请求后端注册数据
    axios
      .post('/api/auth/register', {
        email: this._email,
        password: this.password,
        username: this._username
      })
      .then((response) => {
        // Store token in cookie
        cookies.set('token', response.data.token)
      })
      .catch((error) => {
        console.error(error)
      })
  }

  /**
   * ## 激活用户
   * - 该方法用于用户注册成功后激活注册的用户
   */
  private _activeUser() {
    axios
      .post('/api/auth/active', {
        email: this._email,
        password: this.password,
        username: this._username
      })
      .then((response) => {
        // Store token in cookie
        cookies.set('token', response.data.token)
      })
      .catch((error) => {
        console.error(error)
      })
  }

  /**
   * ## 用户登陆
   * 用户登陆包括两种模式：
   * - 账号密码登陆
   * - 扫码登陆
   */
  public login() {
    axios
      .post('/api/login', { email: this._email, password: this._password })
      .then((response) => {
        // Store token in cookie
        cookies.set('token', response.data.token)
      })
      .catch((error) => {
        console.error(error)
      })
  }

  /**用户登陆 */
  public logout() {
    axios
      .post('/api/auth/logout', { token: cookies.get('token') })
      .then((response) => {
        // Remove token from cookie
        cookies.remove('token')
      })
      .catch((error) => {
        console.error(error)
      })
  }

  // Define get_user_permissions method
  get_user_permissions() {
    return []
  }
}
